package com.onpositive.mediawiki.redirects;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class RefMap implements Map<String,ArrayList<StringPair>>{
	
	private HashMap<String,ArrayList<StringPair>> storage ;
	
	public RefMap( int initialCapacity )
	{
		storage = new HashMap<String, ArrayList<StringPair>>( initialCapacity )	;
	}
	
	public RefMap( Collection<String> set )
	{
		storage = new HashMap<String, ArrayList<StringPair>>() ;
		
//		add( "A_Study_in_Scarlet_(1933_film)" );
//		add( "A_Spark._To_Pierce_the_Dark." );
//		add( "2009_Seguros_Bolivar_Open_Pereira_-_Singles" );
//		add( "!Ay,_Carmela!_(film)" );
//		add( "!Ole_Torme!:_Mel_Torme_Goes_South_of_the_Border_with_Billy_May" );
		//add( "Caudron-Renaut" ) ;
		
		
		for( String str : set )
			add( str ) ;
				
		//sort() ;
	}
	
	private static String getKeyWord(String _str)
	{
		String str = _str.toLowerCase() ;
		int l = str.length(), i = 0 ;
		for( ; i < l && isMark( str.charAt(i) ) ; i++ ) ;			
		int s=i ;			
		for( ; i < l && !isMark( str.charAt(i) ) ; i++ ) ;			
		return str.substring(s,i).toLowerCase().trim() ;
	}
	
	public static String constructPattern(String str)
	{
		StringBuilder builder = new StringBuilder() ;
		int l = str.length();
		for( int i = 0 ; i < l ; i++ )
		{
			char ch = str.charAt(i);
			if( !isMark( ch ) )
				builder.append( ch ) ;
		}			
		return builder.toString().toLowerCase().trim() ;
	}
	
	private static boolean isMark(char ch) {
		
		return ( !Character.isJavaIdentifierPart(ch) || ch == '_' ) ;
	}
	
	public void add( String _str )
	{			
		if( _str == null || _str.trim().length() == 0 )
			return ;
		
		String str = _str.trim().replaceAll(" ", "_") ;
		String keyWord = getKeyWord(str);
		String pattern = constructPattern( str ) ; 
		
		ArrayList<StringPair> arr = storage.get(keyWord) ;
		if( arr == null )
		{
			arr = new ArrayList<StringPair>() ;
			storage.put(keyWord, arr) ;
		}
		for( StringPair sp : arr )
			if( sp.getPattern().equals(pattern) )
				return ;
				
		arr.add( new StringPair( pattern, str ) ) ;
	}				


	
	public void sort()
	{
		Comparator<StringPair> comp = new Comparator<StringPair>() {				
			@Override
			public int compare(StringPair arg0, StringPair arg1) {
				return arg0.getPattern().compareTo( arg1.getPattern() ) ;
			}
		};
		
		for( ArrayList<StringPair> lst : storage.values() )
			Collections.sort( lst, comp ) ;			
	}
	
	

	@Override
	public void clear() {
		storage.clear() ;
	}

	@Override
	public boolean containsKey(Object key) {
		return storage.containsKey(key) ;
	}

	@Override
	public boolean containsValue(Object value) {
		return storage.containsValue(value);
	}

	@Override
	public Set<java.util.Map.Entry<String, ArrayList<StringPair>>> entrySet() {
		return storage.entrySet() ;
	}

	@Override
	public ArrayList<StringPair> get(Object key) {
		
		if( key == null )
			return null ;
		
		String keyWord = getKeyWord( key.toString() ) ;
		if( keyWord == null )
			return null ;
		
		return storage.get( keyWord );
	}
	
	public String getBestMAtch(Object key) {
		
		ArrayList<StringPair> matches = get(key) ;
		String pattern = constructPattern(key.toString());
		for( StringPair sp : matches ){			
			if( sp.getPattern().equals( pattern ) )
				return sp.getValue() ;
		}	
		return null ;		
	}

	@Override
	public boolean isEmpty() {
		return storage.isEmpty();
	}

	@Override
	public Set<String> keySet() {
		return storage.keySet();
	}

	@Override
	public ArrayList<StringPair> put(String key, ArrayList<StringPair> value) {
		return null ; //return storage.put(key, value) ;
	}

	@Override
	public void putAll(Map<? extends String, ? extends ArrayList<StringPair>> m) {
		//storage.putAll(m) ;			
	}

	@Override
	public ArrayList<StringPair> remove(Object key) {	
		if(  !(key instanceof String) )
			return null;
		
		String str = getKeyWord( (String) key );
		return storage.remove( str ) ;			
	}

	@Override
	public int size() {			
		return storage.size();
	}

	@Override
	public Collection<ArrayList<StringPair>> values() {
		return storage.values();
	}
	
	
}

	

